Everything you need to maintain, update, and deploy this site.
SalesWebsite/
├── index.html ← Home / Programme page
├── about/index.html ← About Lovinia
├── pricing/index.html ← Pricing table + flipbook ← NEW
├── faq/index.html ← FAQ ← NEW
├── register/index.html ← Registration + Stripe ← NEW
├── _data/trainer.json ← Shared trainer data ← NEW
├── articles/ ← Articles (existing)
├── privacy-policy.html ← Existing
├── assets/ ← Images and static files
└── _site/ ← Auto-generated. DO NOT EDIT.
Rule: Never edit anything inside _site/. It is overwritten every build.
Every page has a CONFIG block at the top of the <script> section. It is clearly marked:
<!-- CONFIG BLOCK — EDIT THIS SECTION ONLY -->
You never need to touch the HTML below it. All updates go in the CONFIG block.
Open pricing/index.html and register/index.html. Find:
date: "May 5–6, 2025",
earlybird_deadline: "2025-04-05",
Change both values. The early bird countdown and pricing auto-update from these two fields.
Format for earlybird_deadline: Always YYYY-MM-DD. The system calculates 30 days automatically — you set the exact cutoff date, not "30 days before."
Open pricing/index.html. Find the schedule block in CONFIG:
schedule: {
day1: {
title: "Day One",
subtitle: "Foundation & Framework",
sessions: [
{ time:"9:00 – 10:30am", topic:"[ADD: Session title]", detail:"[ADD: description]" },
{ time:"10:30 – 10:45am", topic:"Morning Break", break:true },
...
]
}
}
Replace the [ADD: ...] placeholders. Do not change the time values — those are fixed. Only change topic and detail.
For breaks: Keep break:true and only change the topic text if needed. Do not add detail to break rows.
Open pricing/index.html. Find:
testimonials: [
{ placeholder:true, quote:"", name:"", role:"" },
...
],
Replace with:
{ placeholder:false, quote:"The actual quote from the participant.", name:"First Last", role:"Job Title, Company" },
Set placeholder:false and fill in all three fields. The placeholder card disappears automatically.
Open _data/trainer.json. Edit the paragraphs array. This is the single source of truth — currently only used by the flipbook page. In a future session, we can wire about/index.html to read from this file too, replacing its SITE_CONFIG.
Open pricing/index.html. Find:
announcements: [
"Existing announcement here.",
],
Add a new line inside the array. Use <strong>text</strong> for bold. To remove an announcement, delete its line. To hide all announcements, set the array to [].
Open register/index.html. Find the stripe: block in CONFIG. Replace each "REPLACE_WITH_..." placeholder with the actual Stripe Payment Link URL.
You will have 12 links in total: 3 ticket types × 2 payment methods (card + FPX) × 2 pricing tiers (early bird + standard).
How to get Stripe Payment Links:
https://buy.stripe.com/...)cd ~/Documents/github/SalesWebsite
npm install
cd ~/Documents/github/SalesWebsite
npx eleventy --serve
Opens at http://localhost:8080. Saves automatically on file changes.
cd ~/Documents/github/SalesWebsite
npx eleventy && wrangler deploy
This builds the _site/ folder then pushes to Cloudflare Workers.
cd ~/Documents/github/SalesWebsite
git add -A
git commit -m "describe what you changed"
git push
Do this after every change. Habit, not optional.
Run these commands once to add the new pages:
# Copy new pages
cp -r ~/Desktop/SalesWebsite-build/pricing ~/Documents/github/SalesWebsite/
cp -r ~/Desktop/SalesWebsite-build/faq ~/Documents/github/SalesWebsite/
cp -r ~/Desktop/SalesWebsite-build/register ~/Documents/github/SalesWebsite/
cp -r ~/Desktop/SalesWebsite-build/_data ~/Documents/github/SalesWebsite/
# Fix the broken pricing link in index.html
sed -i '' 's|PRICING-PAGE-LINK-HERE|/pricing/|g' ~/Documents/github/SalesWebsite/index.html
Then verify Eleventy sees the new folders:
cd ~/Documents/github/SalesWebsite && npx eleventy --dryrun 2>&1 | grep -E "pricing|faq|register"
You should see three lines — one for each new page.
Your site is hosted on Cloudflare Workers — not a traditional web server. Think of it as a very fast delivery network that runs your site from data centres closest to each visitor. Zero monthly cost on the free tier.
This is more than enough for your current scale.
This is for the "Notify Me" form on the pricing page and the in-house enquiry form on the register page. Both currently send a POST request to https://YOUR-WORKER.workers.dev/.... You need to create a Worker to receive and store these.
Step-by-step:
cac-leadsexport default {
async fetch(request, env) {
if (request.method === 'OPTIONS') {
return new Response(null, {
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'POST',
'Access-Control-Allow-Headers': 'Content-Type',
}
});
}
if (request.method !== 'POST') {
return new Response('Not found', { status: 404 });
}
const url = new URL(request.url);
const body = await request.json();
const key = `${url.pathname.replace('/','')}_${Date.now()}_${Math.random().toString(36).slice(2,7)}`;
await env.LEADS.put(key, JSON.stringify(body));
return new Response(JSON.stringify({ ok: true }), {
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
}
});
}
};
LEADS, create a new namespace called cac-leads-kvhttps://cac-leads.YOUR-SUBDOMAIN.workers.dev)pricing/index.html and register/index.html, replace https://YOUR-WORKER.workers.dev with your actual worker URLTo read your leads:
wrangler kv:key list --namespace-id YOUR_KV_NAMESPACE_ID
wrangler kv:key get --namespace-id YOUR_KV_NAMESPACE_ID "key_name_here"
Or export all:
wrangler kv:key list --namespace-id YOUR_KV_NAMESPACE_ID > leads_keys.txt
Get your namespace ID from the Cloudflare dashboard → Workers & Pages → KV.
npx eleventy --serve and check all three new pages loadregister/index.html CONFIGpricing/index.html CONFIGpricing/index.html CONFIGpricing/index.html CONFIGdate and earlybird_deadline in BOTH pricing/index.html and register/index.htmlgit add -A && git commit -m "what changed" && git pushnpx eleventy && wrangler deploy| From | To | How |
|---|---|---|
| index.html | /pricing/ | "Pricing Table" link in module section (now fixed) |
| pricing/index.html | /register/ | "Register Now" button |
| pricing/index.html | /faq/ | "FAQ" button |
| pricing/index.html | /about/ | Trainer flipbook page + event bar |
| faq/index.html | /pricing/ | Refund/guarantee policy links |
| faq/index.html | /register/ | "Register Now" CTA |
| register/index.html | /pricing/ | "Terms apply" link |
| register/index.html | /faq/ | "Payment FAQ" link |
| All pages | / | Logo and "Programme" nav link |
| All pages | /about/ | Event bar + footer |
| All pages | /articles/ | Event bar |
| All pages | /privacy-policy/ | Footer |
_site/ — auto-generated, always overwrittennode_modules/ — dependency folder, never editpackage-lock.json — auto-managedPage not showing after deploy:
npx eleventy --dryrun
Look for errors. Usually a missing file or malformed path.
Eleventy build fails:
npx eleventy 2>&1 | head -40
Read the first error. Usually a Liquid/Nunjucks syntax error in a template.
Wrangler deploy fails:
wrangler whoami
If not logged in: wrangler login
Local preview not updating:
Stop the server (Ctrl+C), clear _site/:
rm -rf _site && npx eleventy --serve
End of manual. Version 1.0 — April 2026.
Enquiry form at sales-training/enquiry stopped working after CRM was built.
cac-leads.../corporate-enquiry (lead capture worker). Should be cac-corporate-enquiry.clarityawarenesscoaching.workers.dev. Fixed in sales-training/enquiry/index.html.D1 instead of DB. Worker code uses env.DB. Fixed manually on dashboard (rename binding to DB).contacts table. Live contacts is a B2B company master (company_name, general_email, pic_name — not a person/lead table). Enquiry data belongs in enquiries table. Fixed in src/index.js.outcome and initiated_by which don't exist in live interactions table. Live schema has worker_event instead. Fixed.interactions.contact_id has a foreign key on contacts(id). Enquiry row id is not a contacts id. Removed interactions insert entirely — enquiries table is the log for this worker.sales-training/enquiry/index.html — worker URL fixworkers/cac-corporate-enquiry/src/index.js — DB writes correctedenquiries — id INTEGER PK (autoincrement), name, email, phone, company, company_address, course, pax, tentative_date, venue, hrdc_option, message, status, created_atinteractions — id INTEGER PK, contact_id INTEGER (FK → contacts.id), direction, channel, summary, worker_event, resend_email_id, created_atemail_events — id TEXT PK, contact_id TEXT (no FK), campaign_id, sequence_step, resend_email_id, event_type, event_time, metadatacontacts — id INTEGER PK, company_name, general_email, phone, pic_name, hr_name, hr_email, linkedin_url, source, outreach_status, preferred_training, campaign_id, assigned_course, created_at, updated_at, tax_metadataReplicate the sales-training/enquiry workflow for the Training Provider (New Rise or equivalent).
Subdomain: newrise.claritysystems.work/enquiry (or similar).
| Item | CAC (current) | New Rise (next build) |
|---|---|---|
| Form branding | CAC logo, colours | TP company name/brand |
| Worker | cac-corporate-enquiry | newrise-corporate-enquiry |
| Proforma issuer | Clarity Awareness Coaching | TP details + billing |
| Trainer profile | CAC trainer profile PDF | Same or TP-specific version |
| Database | claritysystems-db → enquiries | New D1 OR new table in claritysystems-db OR Google Sheet |
| Email sender | [email protected] | TP email (TBC) |
| Telegram notify | CAC Telegram | Same or new channel (TBC) |
newrise-corporate-enquiry — TP details in proforma, payment, issued-by blocksnewrise_enquiries in same claritysystems-db, zero new infrastructure)Read BUILD_LOG.md and my work notes/OWNERS_MANUAL.md (New Rise section).
Task: Build the New Rise TP enquiry flow.
Stack: Same as CAC — Cloudflare Pages subdomain + new Worker + claritysystems-db (new table newrise_enquiries).
Start with:
1. Duplicate sales-training/enquiry/index.html → newrise/enquiry/index.html with TP branding
2. Duplicate workers/cac-corporate-enquiry → workers/newrise-corporate-enquiry with TP details
3. Add newrise_enquiries table to claritysystems-db
4. Wire subdomain newrise.claritysystems.work on Cloudflare Pages
TP details: [INSERT BEFORE SESSION]